package com.chuangke.sinotrukbudget.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.common.utils.FileUtils;
import com.chuangke.core.exception.ChuangkeException;
import com.chuangke.framework.model.Record;
import com.chuangke.olap.OlapProcessor;
import com.chuangke.olap.model.OlapFactor;
import com.chuangke.olap.model.Property;
import com.chuangke.olap.model.RowOlapFactor;
import com.chuangke.olap.processor.MultiOlapProcessor;
import com.chuangke.olap.view.feview.FeViewBuilder;
import com.chuangke.sinotrukbudget.consts.BudgetContanst;
import com.chuangke.sinotrukbudget.domain.BudgetOlapPackage;
import com.chuangke.sinotrukbudget.manager.BudgetManager;
import com.chuangke.sinotrukbudget.model.BudgetBpcPlan;
import com.chuangke.sinotrukbudget.sdao.BudgetBpcPlanDaoService;
import com.chuangke.sinotrukbudget.service.BudgetBpcDrillDownService;
import com.chuangke.sinotrukbudget.util.BudgetUtil;

@Service
public class BudgetBpcDrillDownServiceImpl implements BudgetBpcDrillDownService {

	private static Map<String, BudgetOlapPackage> budgetMap = new HashMap<>();
	static {
		String file = FileUtils.getFileStr("classpath:budget_detail_config.json");
		List<BudgetOlapPackage> list = JSON.parseArray(file, BudgetOlapPackage.class);
		List<String> accountList = new ArrayList<>() ;
		for(BudgetOlapPackage bop : list) {
			if(accountList.contains(bop.getAccountId())) {
				throw new ChuangkeException(String.format("科目%s多次配置", bop.getAccountId())) ;
			}
			accountList.add(bop.getAccountId()) ;
		}
		budgetMap = list.stream().collect(Collectors.toMap(BudgetOlapPackage::getAccountId, a -> a));
	}

	@Autowired
	private BudgetBpcPlanDaoService budgetBpcPlanDaoService;
	@Autowired
	private BudgetManager budgetManager;

	@Override
	public Map<String, Object> list(String category, String accountId, String deptId) {
		if (!budgetMap.keySet().contains(accountId)) {
			throw new ChuangkeException(String.format("科目[%s]暂无明细信息，", accountId));
		}

		BudgetOlapPackage budgetOlapPackage = budgetMap.get(accountId);
		
		Map<String, String> rowDimensionMap = new HashMap<>();

		for (RowOlapFactor rowDimension : budgetOlapPackage.getOlapPackages().get(0).getRowDimensions()) {
			rowDimensionMap.put(rowDimension.getColumn(), rowDimension.getColumnName());
			if (CollectionUtils.isEmpty(rowDimension.getExtendFactors())) {
				continue;
			}
			for (RowOlapFactor extendRowDimension : rowDimension.getExtendFactors()) {
				rowDimensionMap.put(extendRowDimension.getAlias(), extendRowDimension.getColumnName());
			}
		}

		List<BudgetBpcPlan> list = queryBudget(category, Arrays.asList(deptId), Arrays.asList(accountId));

		List<Record> dataSource = BudgetUtil.convert(list);

		List<Property> propertys = budgetManager.getProperty(rowDimensionMap);

		List<List<Record>> dataSourceList = new ArrayList<>();
		dataSourceList.add(dataSource);
		List<Record> dataSource1 = new ArrayList<>();
		dataSource1.addAll(dataSource);
		dataSourceList.add(dataSource1);

		OlapProcessor olapProcessor = new MultiOlapProcessor(propertys, budgetOlapPackage.getOlapPackages(),
				dataSourceList);
		olapProcessor.build();

		FeViewBuilder feViewBuilder = FeViewBuilder.build(olapProcessor.getColumns());
		
		List<Map<String, Object>> data = olapProcessor.getData() ;
		data.forEach(d->d.put("status", "1"));

		Map<String, Object> result = new HashMap<>();
		result.put("columns", feViewBuilder.getColumns());
		result.put("datas", olapProcessor.getData());
		return result;
	}

	private List<BudgetBpcPlan> queryBudget(String category, List<String> deptIds, List<String> accountIds) {
		QueryWrapper<BudgetBpcPlan> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(BudgetBpcPlan::gettCategory, category);
		queryWrapper.lambda().in(BudgetBpcPlan::gettEntity, deptIds);
		queryWrapper.lambda().in(BudgetBpcPlan::gettAccount, accountIds);
		queryWrapper.lambda().eq(BudgetBpcPlan::gettAudit, BudgetContanst.BUDGET_AUDIT_INPUT) ;

		return budgetBpcPlanDaoService.list(queryWrapper);
	}

}